home *** CD-ROM | disk | FTP | other *** search
/ The Atari Compendium / The Atari Compendium (Toad Computers) (1994).iso / files / prgtools / gnustuff / tos / updates / update34.zoo / include / math-68881.h
Encoding:
C/C++ Source or Header  |  1993-10-28  |  9.3 KB  |  540 lines

  1. #ifndef _MATH_68881_H
  2. #define _MATH_68881_H
  3.  
  4. /******************************************************************\
  5. *                                   *
  6. *  <math-68881.h>        last modified: 23 May 1992.       *
  7. *                                   *
  8. *  Copyright (C) 1989 by Matthew Self.                   *
  9. *  You may freely distribute verbatim copies of this software       *
  10. *  provided that this copyright notice is retained in all copies.  *
  11. *  You may distribute modifications to this software under the     *
  12. *  conditions above if you also clearly note such modifications    *
  13. *  with their author and date.                               *
  14. *                                   *
  15. *  Note:  errno is not set to EDOM when domain errors occur for    *
  16. *  most of these functions.  Rather, it is assumed that the       *
  17. *  68881's OPERR exception will be enabled and handled           *
  18. *  appropriately by the    operating system.  Similarly, overflow       *
  19. *  and underflow do not set errno to ERANGE.               *
  20. *                                   *
  21. *  Send bugs to Matthew Self (self@bayes.arc.nasa.gov).           *
  22. *                                   *
  23. \******************************************************************/
  24.  
  25. /* If you find this in GCC,
  26.    please send bug reports to bug-gcc@prep.ai.mit.edu.  */
  27.  
  28. /* Changed by Richard Stallman: % inserted before a #.
  29.    New function `hypot' added.
  30.    Nans written in hex to avoid 0rnan.
  31.    May 1992, use %! for fpcr register.  Break lines before function names.
  32.    December 1989, add parens around `&' in pow.
  33.    November 1990, added alternate definition of HUGE_VAL for Sun.  */
  34.  
  35. #include <errno.h>
  36.  
  37. #ifdef __cplusplus
  38. extern "C" {
  39. #endif
  40.  
  41. #ifndef HUGE_VAL
  42. #ifdef __sun__
  43. /* The Sun assembler fails to handle the hex constant in the usual defn.  */
  44. #define HUGE_VAL                            \
  45. ({                                    \
  46.   static union { int i[2]; double d; } u = { {0x7ff00000, 0} };        \
  47.   u.d;                                    \
  48. })
  49. #else
  50. #define HUGE_VAL                            \
  51. ({                                    \
  52.   double huge_val;                            \
  53.                                     \
  54.   __asm ("fmove%.d %#0x7ff0000000000000,%0"    /* Infinity */        \
  55.      : "=f" (huge_val)                        \
  56.      : /* no inputs */);                        \
  57.   huge_val;                                \
  58. })
  59. #endif
  60. #endif
  61.  
  62. __inline static const double
  63. sin (double x)
  64. {
  65.   double value;
  66.  
  67.   __asm ("fsin%.x %1,%0"
  68.      : "=f" (value)
  69.      : "f" (x));
  70.   return value;
  71. }
  72.  
  73. __inline static const double
  74. cos (double x)
  75. {
  76.   double value;
  77.  
  78.   __asm ("fcos%.x %1,%0"
  79.      : "=f" (value)
  80.      : "f" (x));
  81.   return value;
  82. }
  83.  
  84. __inline static const double
  85. tan (double x)
  86. {
  87.   double value;
  88.  
  89.   __asm ("ftan%.x %1,%0"
  90.      : "=f" (value)
  91.      : "f" (x));
  92.   return value;
  93. }
  94.  
  95. __inline static const double
  96. asin (double x)
  97. {
  98.   double value;
  99.  
  100.   __asm ("fasin%.x %1,%0"
  101.      : "=f" (value)
  102.      : "f" (x));
  103.   return value;
  104. }
  105.  
  106. __inline static const double
  107. acos (double x)
  108. {
  109.   double value;
  110.  
  111.   __asm ("facos%.x %1,%0"
  112.      : "=f" (value)
  113.      : "f" (x));
  114.   return value;
  115. }
  116.  
  117. __inline static const double
  118. atan (double x)
  119. {
  120.   double value;
  121.  
  122.   __asm ("fatan%.x %1,%0"
  123.      : "=f" (value)
  124.      : "f" (x));
  125.   return value;
  126. }
  127.  
  128. __inline static const double
  129. atan2 (double y, double x)
  130. {
  131.   double pi, pi_over_2;
  132.  
  133.   __asm ("fmovecr%.x %#0,%0"        /* extended precision pi */
  134.      : "=f" (pi)
  135.      : /* no inputs */ );
  136.   __asm ("fscale%.b %#-1,%0"        /* no loss of accuracy */
  137.      : "=f" (pi_over_2)
  138.      : "0" (pi));
  139.   if (x > 0)
  140.     {
  141.       if (y > 0)
  142.     {
  143.       if (x > y)
  144.         return atan (y / x);
  145.       else
  146.         return pi_over_2 - atan (x / y);
  147.     }
  148.       else
  149.     {
  150.       if (x > -y)
  151.         return atan (y / x);
  152.       else
  153.         return - pi_over_2 - atan (x / y);
  154.     }
  155.     }
  156.   else
  157.     {
  158.       if (y > 0)
  159.     {
  160.       if (-x > y)
  161.         return pi + atan (y / x);
  162.       else
  163.         return pi_over_2 - atan (x / y);
  164.     }
  165.       else
  166.     {
  167.       if (-x > -y)
  168.         return - pi + atan (y / x);
  169.       else if (y < 0)
  170.         return - pi_over_2 - atan (x / y);
  171.       else
  172.         {
  173.           double value;
  174.  
  175.           errno = EDOM;
  176.           __asm ("fmove%.d %#0x7fffffffffffffff,%0"     /* quiet NaN */
  177.              : "=f" (value)
  178.              : /* no inputs */);
  179.           return value;
  180.         }
  181.     }
  182.     }
  183. }
  184.  
  185. __inline static const double
  186. sinh (double x)
  187. {
  188.   double value;
  189.  
  190.   __asm ("fsinh%.x %1,%0"
  191.      : "=f" (value)
  192.      : "f" (x));
  193.   return value;
  194. }
  195.  
  196. __inline static const double
  197. cosh (double x)
  198. {
  199.   double value;
  200.  
  201.   __asm ("fcosh%.x %1,%0"
  202.      : "=f" (value)
  203.      : "f" (x));
  204.   return value;
  205. }
  206.  
  207. __inline static const double
  208. tanh (double x)
  209. {
  210.   double value;
  211.  
  212.   __asm ("ftanh%.x %1,%0"
  213.      : "=f" (value)
  214.      : "f" (x));
  215.   return value;
  216. }
  217.  
  218. __inline static const double
  219. atanh (double x)
  220. {
  221.   double value;
  222.  
  223.   __asm ("fatanh%.x %1,%0"
  224.      : "=f" (value)
  225.      : "f" (x));
  226.   return value;
  227. }
  228.  
  229. __inline static const double
  230. exp (double x)
  231. {
  232.   double value;
  233.  
  234.   __asm ("fetox%.x %1,%0"
  235.      : "=f" (value)
  236.      : "f" (x));
  237.   return value;
  238. }
  239.  
  240. __inline static const double
  241. expm1 (double x)
  242. {
  243.   double value;
  244.  
  245.   __asm ("fetoxm1%.x %1,%0"
  246.      : "=f" (value)
  247.      : "f" (x));
  248.   return value;
  249. }
  250.  
  251. __inline static const double
  252. log (double x)
  253. {
  254.   double value;
  255.  
  256.   __asm ("flogn%.x %1,%0"
  257.      : "=f" (value)
  258.      : "f" (x));
  259.   return value;
  260. }
  261.  
  262. __inline static const double
  263. log1p (double x)
  264. {
  265.   double value;
  266.  
  267.   __asm ("flognp1%.x %1,%0"
  268.      : "=f" (value)
  269.      : "f" (x));
  270.   return value;
  271. }
  272.  
  273. __inline static const double
  274. log10 (double x)
  275. {
  276.   double value;
  277.  
  278.   __asm ("flog10%.x %1,%0"
  279.      : "=f" (value)
  280.      : "f" (x));
  281.   return value;
  282. }
  283.  
  284. __inline static const double
  285. sqrt (double x)
  286. {
  287.   double value;
  288.  
  289.   __asm ("fsqrt%.x %1,%0"
  290.      : "=f" (value)
  291.      : "f" (x));
  292.   return value;
  293. }
  294.  
  295. __inline static const double
  296. _sqrt (double x)
  297. {
  298.   double value;
  299.  
  300.   __asm ("fsqrt%.x %1,%0"
  301.      : "=f" (value)
  302.      : "f" (x));
  303.   return value;
  304. }
  305.  
  306. __inline static const double
  307. hypot (const double x, const double y)
  308. {
  309.   return _sqrt (x*x + y*y);
  310. }
  311.  
  312. __inline static const double
  313. pow (const double x, const double y)
  314. {
  315.   if (x > 0)
  316.     return exp (y * log (x));
  317.   else if (x == 0)
  318.     {
  319.       if (y > 0)
  320.     return 0.0;
  321.       else
  322.     {
  323.       double value;
  324.  
  325.       errno = EDOM;
  326.       __asm ("fmove%.d %#0x7fffffffffffffff,%0"        /* quiet NaN */
  327.          : "=f" (value)
  328.          : /* no inputs */);
  329.       return value;
  330.     }
  331.     }
  332.   else
  333.     {
  334.       double temp;
  335.  
  336.       __asm ("fintrz%.x %1,%0"
  337.          : "=f" (temp)            /* integer-valued float */
  338.          : "f" (y));
  339.       if (y == temp)
  340.         {
  341.       int i = (int) y;
  342.       
  343.       if ((i & 1) == 0)            /* even */
  344.         return exp (y * log (-x));
  345.       else
  346.         return - exp (y * log (-x));
  347.         }
  348.       else
  349.         {
  350.       double value;
  351.  
  352.       errno = EDOM;
  353.       __asm ("fmove%.d %#0x7fffffffffffffff,%0"        /* quiet NaN */
  354.          : "=f" (value)
  355.          : /* no inputs */);
  356.       return value;
  357.         }
  358.     }
  359. }
  360.  
  361. __inline static const double
  362. fabs (double x)
  363. {
  364.   double value;
  365.  
  366.   __asm ("fabs%.x %1,%0"
  367.      : "=f" (value)
  368.      : "f" (x));
  369.   return value;
  370. }
  371.  
  372. __inline static const double
  373. ceil (double x)
  374. {
  375.   int rounding_mode, round_up;
  376.   double value;
  377.  
  378.   __asm volatile ("fmove%.l %!,%0"
  379.           : "=dm" (rounding_mode)
  380.           : /* no inputs */ );
  381.   round_up = rounding_mode | 0x30;
  382.   __asm volatile ("fmove%.l %0,%!"
  383.           : /* no outputs */
  384.           : "dmi" (round_up));
  385.   __asm volatile ("fint%.x %1,%0"
  386.           : "=f" (value)
  387.           : "f" (x));
  388.   __asm volatile ("fmove%.l %0,%!"
  389.           : /* no outputs */
  390.           : "dmi" (rounding_mode));
  391.   return value;
  392. }
  393.  
  394. __inline static const double
  395. floor (double x)
  396. {
  397.   int rounding_mode, round_down;
  398.   double value;
  399.  
  400.   __asm volatile ("fmove%.l %!,%0"
  401.           : "=dm" (rounding_mode)
  402.           : /* no inputs */ );
  403.   round_down = (rounding_mode & ~0x10)
  404.         | 0x20;
  405.   __asm volatile ("fmove%.l %0,%!"
  406.           : /* no outputs */
  407.           : "dmi" (round_down));
  408.   __asm volatile ("fint%.x %1,%0"
  409.           : "=f" (value)
  410.           : "f" (x));
  411.   __asm volatile ("fmove%.l %0,%!"
  412.           : /* no outputs */
  413.           : "dmi" (rounding_mode));
  414.   return value;
  415. }
  416.  
  417. __inline static const double
  418. rint (double x)
  419. {
  420.   int rounding_mode, round_nearest;
  421.   double value;
  422.  
  423.   __asm volatile ("fmove%.l %!,%0"
  424.           : "=dm" (rounding_mode)
  425.           : /* no inputs */ );
  426.   round_nearest = rounding_mode & ~0x30;
  427.   __asm volatile ("fmove%.l %0,%!"
  428.           : /* no outputs */
  429.           : "dmi" (round_nearest));
  430.   __asm volatile ("fint%.x %1,%0"
  431.           : "=f" (value)
  432.           : "f" (x));
  433.   __asm volatile ("fmove%.l %0,%!"
  434.           : /* no outputs */
  435.           : "dmi" (rounding_mode));
  436.   return value;
  437. }
  438.  
  439. __inline static const double
  440. fmod (double x, double y)
  441. {
  442.   double value;
  443.  
  444.   __asm ("fmod%.x %2,%0"
  445.      : "=f" (value)
  446.      : "0" (x),
  447.        "f" (y));
  448.   return value;
  449. }
  450.  
  451. __inline static const double
  452. drem (double x, double y)
  453. {
  454.   double value;
  455.  
  456.   __asm ("frem%.x %2,%0"
  457.      : "=f" (value)
  458.      : "0" (x),
  459.        "f" (y));
  460.   return value;
  461. }
  462.  
  463. __inline static const double
  464. scalb (double x, int n)
  465. {
  466.   double value;
  467.  
  468.   __asm ("fscale%.l %2,%0"
  469.      : "=f" (value)
  470.      : "0" (x),
  471.        "dmi" (n));
  472.   return value;
  473. }
  474.  
  475. __inline static double
  476. logb (double x)
  477. {
  478.   double exponent;
  479.  
  480.   __asm ("fgetexp%.x %1,%0"
  481.      : "=f" (exponent)
  482.      : "f" (x));
  483.   return exponent;
  484. }
  485.  
  486. __inline static const double
  487. ldexp (double x, int n)
  488. {
  489.   double value;
  490.  
  491.   __asm ("fscale%.l %2,%0"
  492.      : "=f" (value)
  493.      : "0" (x),
  494.        "dmi" (n));
  495.   return value;
  496. }
  497.  
  498. __inline static double
  499. frexp (double x, int *exp)
  500. {
  501.   double float_exponent;
  502.   int int_exponent;
  503.   double mantissa;
  504.  
  505.   __asm ("fgetexp%.x %1,%0"
  506.      : "=f" (float_exponent)     /* integer-valued float */
  507.      : "f" (x));
  508.   int_exponent = (int) float_exponent;
  509.   __asm ("fgetman%.x %1,%0"
  510.      : "=f" (mantissa)        /* 1.0 <= mantissa < 2.0 */
  511.      : "f" (x));
  512.   if (mantissa != 0)
  513.     {
  514.       __asm ("fscale%.b %#-1,%0"
  515.          : "=f" (mantissa)        /* mantissa /= 2.0 */
  516.          : "0" (mantissa));
  517.       int_exponent += 1;
  518.     }
  519.   *exp = int_exponent;
  520.   return mantissa;
  521. }
  522.  
  523. __inline static double
  524. modf (double x, double *ip)
  525. {
  526.   double temp;
  527.  
  528.   __asm ("fintrz%.x %1,%0"
  529.      : "=f" (temp)            /* integer-valued float */
  530.      : "f" (x));
  531.   *ip = temp;
  532.   return x - temp;
  533. }
  534.  
  535. #ifdef __cplusplus
  536. }
  537. #endif
  538.  
  539. #endif /* _MATH_68881_H */
  540.